package com.maplexl.shiroJwtRedis.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.maplexl.shiroJwtRedis.constant.CommonEnum;
import com.maplexl.shiroJwtRedis.pojo.User;
import com.maplexl.shiroJwtRedis.pojo.vo.Result;
import com.maplexl.shiroJwtRedis.services.UserService;
import com.maplexl.shiroJwtRedis.util.JwtUtil;
import com.maplexl.shiroJwtRedis.util.RedisUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

/**
 * @author 枫叶
 * @date 2020/11/1
 */
@RestController
@Slf4j
public class LoginController {
    @Resource
    UserService userService;

    /**
     * 登录接口
     * @param user 用户
     * @param response 响应
     * @return 登录成功则返回token
     */
    @ApiOperation("登录接口")
    @PostMapping("/login")
    public Result<User> login(@RequestBody User user, HttpServletResponse response) {
        String userName = user.getUserName();
        String password = user.getPassword();
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)) {
            return new Result<>(CommonEnum.INVALID_CHARACTER);
        }
        //查询是否有此用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", userName);
        User dbUser = userService.getOne(wrapper);
        if (dbUser == null) {
            return new Result<>(CommonEnum.NO_SUCH_USER);
        }
        //校验密码
        password = new SimpleHash("MD5", password, dbUser.getSalt(), 32).toString();
        if (password.equals(dbUser.getPassword())) {
            //密码正确
            long timeMillis = System.currentTimeMillis();
            String token = JwtUtil.sign(dbUser.getUserId(), timeMillis);
            dbUser.setPassword(null);
            //token放入redis
            RedisUtil.set(dbUser.getUserId(), timeMillis, JwtUtil.REFRESH_EXPIRE_TIME);
            response.setHeader("Authorization", token);
            response.setHeader("Access-Control-Expose-Headers", "Authorization");
            return new Result<>(CommonEnum.SUCCESS, dbUser);
        }
        return new Result<>(CommonEnum.PASSWORD_ERROR);
    }

    /**
     * 添加用户,即注册
     *
     * @param user 用户信息
     * @return 是否保存成功
     */
    @ApiOperation("注册接口")
    @PostMapping("/register")
    public Result<Boolean> add(@RequestBody User user) {
        //验证用户名是否重复
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name",user.getUserName());
        User dbUser = userService.getOne(wrapper);
        if (dbUser!=null){
            return new Result<>(CommonEnum.USER_EXIST);
        }
        //加密用户的密码
        String salt = UUID.randomUUID().toString().substring(0, 24);
        String password = new SimpleHash("MD5", user.getPassword(), salt, 32).toString();
        user.setSalt(salt);
        user.setPassword(password);
        boolean save = userService.save(user);
        if (save) {
            return new Result<>(CommonEnum.SUCCESS, true);
        }
        return new Result<>(CommonEnum.INVALID_INSERT, false);
    }

    /**
     * 登出
     * @return 是否登出
     */
    @GetMapping("/logout")
    public Result<Boolean> logout(HttpServletRequest request){
        /*
         * 清除redis中的RefreshToken即可
         */
        Long userId = JwtUtil.getUserId(request);
        RedisUtil.del(Long.toString(userId));
        return new Result<>(CommonEnum.SUCCESS);
    }
}
